<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Using Comparators</title>
    <link rel="stylesheet" href="gettingStarted.css" type="text/css" />
    <meta name="generator" content="DocBook XSL Stylesheets V1.73.2" />
    <link rel="start" href="index.html" title="Getting Started with Berkeley DB Java Edition" />
    <link rel="up" href="DBEntry.html" title="Chapter 8. Database Records" />
    <link rel="prev" href="bindAPI.html" title="Using the BIND APIs" />
    <link rel="next" href="dbtUsage.html" title="Database Record Example" />
  </head>
  <body>
    <div class="navheader">
      <table width="100%" summary="Navigation header">
        <tr>
          <th colspan="3" align="center">Using Comparators</th>
        </tr>
        <tr>
          <td width="20%" align="left"><a accesskey="p" href="bindAPI.html">Prev</a> </td>
          <th width="60%" align="center">Chapter 8. Database Records</th>
          <td width="20%" align="right"> <a accesskey="n" href="dbtUsage.html">Next</a></td>
        </tr>
      </table>
      <hr />
    </div>
    <div class="sect1" lang="en" xml:lang="en">
      <div class="titlepage">
        <div>
          <div>
            <h2 class="title" style="clear: both"><a id="comparator"></a>Using Comparators</h2>
          </div>
        </div>
      </div>
      <div class="toc">
        <dl>
          <dt>
            <span class="sect2">
              <a href="comparator.html#writeCompare">Writing Comparators</a>
            </span>
          </dt>
          <dt>
            <span class="sect2">
              <a href="comparator.html#setCompare">Setting Comparators</a>
            </span>
          </dt>
        </dl>
      </div>
      <p>Internally, JE databases are organized as BTrees. 
    This means that most database operations
    (inserts, deletes, reads, and so forth) involve BTree node
    comparisons. This comparison most frequently occurs based on database
    keys, but if your database supports duplicate records then
    comparisons can also occur based on the database data. 
</p>
      <p>
        By default, JE performs all such comparisons using a byte-by-byte
        lexicographic comparison.  This mechanism works well for most data.
        However, in some cases you may need to specify your own comparison
        routine. One frequent reason for this is to perform a language sensitive
        lexical ordering of string keys.
    </p>
      <div class="sect2" lang="en" xml:lang="en">
        <div class="titlepage">
          <div>
            <div>
              <h3 class="title"><a id="writeCompare"></a>Writing Comparators</h3>
            </div>
          </div>
        </div>
        <p>
      You override the default comparison function by providing a Java
      <code class="classname">Comparator</code> class to the database.
      The Java <code class="classname">Comparator</code> interface requires you to implement the
      <code class="methodname">Comparator.compare()</code> method 
      (see <a class="ulink" href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Comparator.html" target="_top">http://java.sun.com/j2se/1.4.2/docs/api/java/util/Comparator.html</a> for details). 
      </p>
        <p>
        JE passes your <code class="methodname">Comparator.compare()</code> method
        the <code class="literal">byte</code> arrays that you stored in the database. If
        you know how your data is organized in the <code class="literal">byte</code>
        array, then you can write a comparison routine that directly examines
        the contents of the arrays.  Otherwise, you have to reconstruct your
        original objects, and then perform the comparison.
      </p>
        <p>
            For example, suppose you want to perform unicode lexical comparisons
            instead of UTF-8 byte-by-byte comparisons. Then you could provide a
            comparator that uses <code class="methodname">String.compareTo()</code>,
            which performs a Unicode comparison of two strings (note that for
            single-byte roman characters, Unicode comparison and UTF-8
            byte-by-byte comparisons are identical – this is something you
            would only want to do if you were using multibyte unicode characters
            with JE). In this case, your comparator would look like the
            following:
      </p>
        <a id="je_dbt14"></a>
        <pre class="programlisting">package je.gettingStarted;

import java.util.Comparator;

public class MyDataComparator implements Comparator {

    public MyDataComparator() {}

    public int compare(Object d1, Object d2) {

        byte[] b1 = (byte[])d1;
        byte[] b2 = (byte[])d2;

        String s1 = new String(b1, "UTF-8");
        String s2 = new String(b2, "UTF-8");
        return s1.compareTo(s2);
    }
} </pre>
      </div>
      <div class="sect2" lang="en" xml:lang="en">
        <div class="titlepage">
          <div>
            <div>
              <h3 class="title"><a id="setCompare"></a>Setting Comparators</h3>
            </div>
          </div>
        </div>
        <p>
        You specify a <code class="classname">Comparator</code> using the following
        methods. Note that by default these methods can only be used at database
        creation time, and they are ignored for normal database opens. Also,
        note that JE uses the no-argument constructor for these comparators.
        Further, it is not allowable for there to be a mutable state in these
        comparators or else unpredictable results will occur.
      </p>
        <div class="itemizedlist">
          <ul type="disc">
            <li>
              <p>
                <code class="methodname">DatabaseConfig.setBtreeComparator()</code>
              </p>
              <p>
            Sets the Java <code class="classname">Comparator</code> class used
            to compare two keys in the database.
          </p>
            </li>
            <li>
              <p>
                <code class="methodname">DatabaseConfig.setDuplicateComparator()</code>
              </p>
              <p>
            Sets the Java <code class="classname">Comparator</code> class used to compare the
            data on two duplicate records in the database. This comparator is
            used only if the database supports duplicate records.
          </p>
            </li>
          </ul>
        </div>
        <p>
        You can use the above methods to set a database's comparator after
        database creation time if  you explicitly indicate that the comparator
        is to be overridden.  You do this by using the following methods:
      </p>
        <div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
          <h3 class="title">Note</h3>
          <p>
        If you override your comparator, the new comparator must preserve the
        sort order implemented by your original comparator.  That is, the new
        comparator and the old comparator must return the same value for the
        comparison of any two valid objects. Failure to observe this constraint
        will cause unpredictable results for your application. 
      </p>
          <p>
        If you want to change the fundamental sort order for your database, back
        up the contents of the database, delete the database, recreate it, and
        then reload its data.
      </p>
        </div>
        <div class="itemizedlist">
          <ul type="disc">
            <li>
              <p>
                <code class="methodname">DatabaseConfig.setOverrideBtreeComparator()</code>
              </p>
              <p>
            If set to <code class="literal">true</code>, causes the database's Btree
            comparator to be overridden with the
            <code class="classname">Comparator</code> specified on 
            <code class="methodname">DatabaseConfig.setBtreeComparator()</code>. This
            method can be used to change the comparator post-environment
            creation.
          </p>
            </li>
            <li>
              <p>
                <code class="methodname">DatabaseConfig.setOverrideDuplicateComparator()</code>
              </p>
              <p>
            If set to <code class="literal">true</code>, causes the database's
            duplicates comparator to be overridden with the
            <code class="classname">Comparator</code> specified on
            <code class="methodname">DatabaseConfig.setDuplicateComparator()</code>.
          </p>
            </li>
          </ul>
        </div>
        <p>For example, to use the <code class="classname">Comparator</code>
      described in the previous section:</p>
        <a id="je_dbt15"></a>
        <pre class="programlisting">package je.gettingStarted;

import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseException;

import java.util.Comparator;    

...


// Environment open omitted for brevity

try {
    // Get the database configuration object
    DatabaseConfig myDbConfig = new DatabaseConfig();
    myDbConfig.setAllowCreate(true);

    // Set the duplicate comparator class
    myDbConfig.setDuplicateComparator(MyDataComparator.class);

    // Open the database that you will use to store your data
    myDbConfig.setSortedDuplicates(true);
    Database myDatabase = myDbEnv.openDatabase(null, "myDb", myDbConfig); 
} catch (DatabaseException dbe) {
    // Exception handling goes here
}</pre>
      </div>
    </div>
    <div class="navfooter">
      <hr />
      <table width="100%" summary="Navigation footer">
        <tr>
          <td width="40%" align="left"><a accesskey="p" href="bindAPI.html">Prev</a> </td>
          <td width="20%" align="center">
            <a accesskey="u" href="DBEntry.html">Up</a>
          </td>
          <td width="40%" align="right"> <a accesskey="n" href="dbtUsage.html">Next</a></td>
        </tr>
        <tr>
          <td width="40%" align="left" valign="top">Using the BIND APIs </td>
          <td width="20%" align="center">
            <a accesskey="h" href="index.html">Home</a>
          </td>
          <td width="40%" align="right" valign="top"> Database Record Example</td>
        </tr>
      </table>
    </div>
  </body>
</html>
